#include<fuquOS/idt.h>
#include<fuquOS/gdt.h>
#include<fuquOS/printk.h>
#include<fuquOS/idt_table.h>
#include<fuquOS/kernel_conf.h>
#include<fuquOS/io.h>

extern void pit_handler_entry();

/**
 * @brief 中断服务程序引导注册函数(本质就是在设置异常向量表)
 * 
 */
void notify_registration_isr(){
	#ifdef ENABLE_ISR_DIVIDE_ERROR
	set_idt_entry(0,(u32)isr_divide_error,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_DEBUG
	set_idt_entry(1,(u32)isr_debug,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_NMI
	set_idt_entry(2,(u32)isr_nmi,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_BREAKPOINT
	set_idt_entry(3,(u32)isr_breakpoint,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_OVERFLOW
	set_idt_entry(4,(u32)isr_overflow,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_BOUND_RANGE_EXCEEDED
	set_idt_entry(5,(u32)isr_bound_range_exceeded,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_INVALID_OPCODE
	set_idt_entry(6,(u32)isr_invalid_opcode,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_DEVICE_NOT_AVAILABLE
	set_idt_entry(7,(u32)isr_device_not_available,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_DOUBLE_FAULT
	set_idt_entry(8,(u32)isr_double_fault,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_COPROCESSOR_SEGMENT_OVERRUN
	set_idt_entry(9,(u32)isr_coprocessor_segment_overrun,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_INVALID_TSS
	set_idt_entry(10,(u32)isr_invalid_tss,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_SEGMENT_NOT_PRESENT
	set_idt_entry(11,(u32)isr_segment_not_present,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_STACK_SEGMENT_FAULT
	set_idt_entry(12,(u32)isr_stack_segment_fault,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_GENERAL_PROTECTION
	set_idt_entry(13,(u32)isr_general_protection,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_PAGE_FAULT
	set_idt_entry(14,(u32)isr_page_fault,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_RESERVED
	set_idt_entry(15,(u32)isr_reserved,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_X87_FPU_ERROR
	set_idt_entry(16,(u32)isr_x87_fpu_error,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_ALIGNMENT_CHECK
	set_idt_entry(17,(u32)isr_alignment_check,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_MACHINE_CHECK
	set_idt_entry(18,(u32)isr_machine_check,SEL_KERN_CODE,0x8e);
	#endif
	#ifdef ENABLE_ISR_SIMD_FLOATING_POINT
	set_idt_entry(19,(u32)isr_simd_floating_point,SEL_KERN_CODE,0x8e);
	#endif
	// 时钟中断
	set_idt_entry(32,(u32)pit_handler_entry,SEL_KERN_CODE,0x8e);

}

/**
 * @brief 除零错误异常处理函数 (#DE 0)
 * 
 * @param frame 异常堆栈帧
 */
void isr_divide_error(exception_stack_frame *frame){
	// 这里可以处理异常信息，例如打印错误信息
    printk_err("Exception 0 occurred at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_DIVIDE_ERROR
	asm volatile("hlt");
	#endif
}

/**
 * @brief 调试异常处理函数 (#DB 1)
 * 
 * @param frame 异常堆栈帧
 */
void isr_debug(exception_stack_frame *frame){
	printk_err("Exception 1 (Debug) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_DEBUG
	asm volatile("hlt");
	#endif
}

/**
 * @brief 非屏蔽中断处理函数 (#NMI 2)
 * 
 * @param frame 异常堆栈帧
 */
void isr_nmi(exception_stack_frame *frame){
	printk_err("Exception 2 (Non-Maskable Interrupt) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_NMI
	asm volatile("hlt");
	#endif
}

/**
 * @brief 断点异常处理函数 (#BP 3)
 * 
 * @param frame 异常堆栈帧
 */
void isr_breakpoint(exception_stack_frame *frame){
	printk_err("Exception 3 (Breakpoint) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_BREAKPOINT
	asm volatile("hlt");
	#endif
}

/**
 * @brief 溢出异常处理函数 (#OF 4)
 * 
 * @param frame 异常堆栈帧
 */
void isr_overflow(exception_stack_frame *frame){
	printk_err("Exception 4 (Overflow) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_OVERFLOW
	asm volatile("hlt");
	#endif
}

/**
 * @brief 数组边界超限异常处理函数 (#BR 5)
 * 
 * @param frame 异常堆栈帧
 */
void isr_bound_range_exceeded(exception_stack_frame *frame){
	printk_err("Exception 5 (Bound Range Exceeded) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_BOUND_RANGE_EXCEEDED
	asm volatile("hlt");
	#endif
}

/**
 * @brief 无效指令异常处理函数 (#UD 6)
 * 
 * @param frame 异常堆栈帧
 */
void isr_invalid_opcode(exception_stack_frame *frame){
	printk_err("Exception 6 (Invalid Opcode) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_INVALID_OPCODE
	asm volatile("hlt");
	#endif
}

/**
 * @brief 设备不可用异常处理函数 (#NM 7)
 * 
 * @param frame 异常堆栈帧
 */
void isr_device_not_available(exception_stack_frame *frame){
	printk_err("Exception 7 (Device Not Available) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_DEVICE_NOT_AVAILABLE
	asm volatile("hlt");
	#endif
}

/**
 * @brief 双重错误异常处理函数 (#DF 8)
 * 
 * @param frame 异常堆栈帧
 * @param error_code 错误代码
 */
void isr_double_fault(exception_stack_frame *frame, u32 error_code){
	printk_err("Exception 8 (Double Fault) at EIP: %p, Error Code: %x\n", frame->eip, error_code);
	#ifdef ENABLE_ISR_HLT_DOUBLE_FAULT
	asm volatile("hlt");
	#endif
}

/**
 * @brief 协处理器段超限异常处理函数 (#9)
 * 
 * @param frame 异常堆栈帧
 */
void isr_coprocessor_segment_overrun(exception_stack_frame *frame){
	printk_err("Exception 9 (Coprocessor Segment Overrun) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_COPROCESSOR_SEGMENT_OVERRUN
	asm volatile("hlt");
	#endif
}

/**
 * @brief 无效 TSS 异常处理函数 (#TS 10)
 * 
 * @param frame 异常堆栈帧
 * @param error_code 错误代码
 */
void isr_invalid_tss(exception_stack_frame *frame, u32 error_code){
	printk_err("Exception 10 (Invalid TSS) at EIP: %p, Error Code: %u\n", frame->eip, error_code);
	#ifdef ENABLE_ISR_HLT_INVALID_TSS
	asm volatile("hlt");
	#endif
}

/**
 * @brief 段不存在异常处理函数 (#NP 11)
 * 
 * @param frame 异常堆栈帧
 * @param error_code 错误代码
 */
void isr_segment_not_present(exception_stack_frame *frame, u32 error_code){
	printk_err("Exception 11 (Segment Not Present) at EIP: %p, Error Code: %u\n", frame->eip, error_code);
	#ifdef ENABLE_ISR_HLT_SEGMENT_NOT_PRESENT
	asm volatile("hlt");
	#endif
}

/**
 * @brief 堆栈段错误异常处理函数 (#SS 12)
 * 
 * @param frame 异常堆栈帧
 * @param error_code 错误代码
 */
void isr_stack_segment_fault(exception_stack_frame *frame, u32 error_code){
	printk_err("Exception 12 (Stack Segment Fault) at EIP: %p, Error Code: %u\n", frame->eip, error_code);
	#ifdef ENABLE_ISR_HLT_STACK_SEGMENT_FAULT
	asm volatile("hlt");
	#endif
}

/**
 * @brief 通用保护异常处理函数 (#GP 13)
 * 
 * @param frame 异常堆栈帧
 * @param error_code 错误代码
 */
void isr_general_protection(exception_stack_frame *frame, u32 error_code){
	printk_err("Exception 13 (General Protection Fault) at EIP: %p, Error Code: %u\n", frame->eip, error_code);
	#ifdef ENABLE_ISR_HLT_GENERAL_PROTECTION
	asm volatile("hlt");
	#endif
}

/**
 * @brief 页面错误异常处理函数 (#PF 14)
 * 
 * @param frame 异常堆栈帧
 * @param error_code 错误代码
 */
void isr_page_fault(exception_stack_frame *frame, u32 error_code){
	printk_err("Exception 14 (Page Fault) at EIP: %p, Error Code: %u\n", frame->eip, error_code);
	#ifdef ENABLE_ISR_HLT_PAGE_FAULT
	asm volatile("hlt");
	#endif
}

/**
 * @brief 保留异常处理函数 (#15)
 * 
 * @param frame 异常堆栈帧
 */
void isr_reserved(exception_stack_frame *frame){
	printk_err("Exception 15 (Reserved) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_RESERVED
	asm volatile("hlt");
	#endif
}

/**
 * @brief x87 浮点异常处理函数 (#MF 16)
 * 
 * @param frame 异常堆栈帧
 */
void isr_x87_fpu_error(exception_stack_frame *frame){
	printk_err("Exception 16 (x87 FPU Error) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_X87_FPU_ERROR
	asm volatile("hlt");
	#endif
}

/**
 * @brief 对齐检查异常处理函数 (#AC 17)
 * 
 * @param frame 异常堆栈帧
 * @param error_code 错误代码
 */
void isr_alignment_check(exception_stack_frame *frame, u32 error_code){
	printk_err("Exception 17 (Alignment Check) at EIP: %p, Error Code: %u\n", frame->eip, error_code);
	#ifdef ENABLE_ISR_HLT_ALIGNMENT_CHECK
	asm volatile("hlt");
	#endif
}

/**
 * @brief 机器检查异常处理函数 (#MC 18)
 * 
 * @param frame 异常堆栈帧
 */
void isr_machine_check(exception_stack_frame *frame){
	printk_err("Exception 18 (Machine Check) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_MACHINE_CHECK
	asm volatile("hlt");
	#endif
}

/**
 * @brief SIMD 浮点异常处理函数 (#XM 19)
 * 
 * @param frame 异常堆栈帧
 */
void isr_simd_floating_point(exception_stack_frame *frame){
	printk_err("Exception 19 (SIMD Floating Point) at EIP: %p\n", frame->eip);
	#ifdef ENABLE_ISR_HLT_SIMD_FLOATING_POINT
	asm volatile("hlt");
	#endif

}

volatile u32 tick = 0;
void pit_handler() {
    tick++;
    // 发送EOI通知PIC
    outb(0x20, 0x20);
}

__asm__(
    ".globl pit_handler_entry\n"
    "pit_handler_entry:\n"
    "    pusha\n"
    "    call pit_handler\n"
    "    popa\n"
    "    iret\n"
);

